#include"myheadd.h"



#define SHARED_DIR_TEMPLATE "./Shared_%s"                    //本身的共享目录格式：./Shared_用户名
#define SHARED_DOWNLOAD_DIR_TEMPLATE "./SharedDownload_%s"  //从别人那下东西的目录 ./SharedDownload_用户名


static void get_shared_dir(const char *username, char *buf, size_t buf_size)//拼接函数
{
    snprintf(buf, buf_size, SHARED_DIR_TEMPLATE, username);
}

static void get_shared_download_dir(const char *username, char *buf, size_t buf_size)//拼接函数+1 
{
    snprintf(buf, buf_size, SHARED_DOWNLOAD_DIR_TEMPLATE, username);
}


void shared_init(const char *username) //搭配shared_start_service使用
{
    if (!username || strlen(username) == 0) 
    {
        printf("错误：用户名为空，无法初始化共享目录\n");
        return;
    }

    char shared_dir[256] = {0};
    char download_dir[256] = {0};
    get_shared_dir(username, shared_dir, sizeof(shared_dir));
    get_shared_download_dir(username, download_dir, sizeof(download_dir));

  
    if (access(shared_dir, F_OK) == -1) 
    {
        if (mkdir(shared_dir, 0755) == 0) //0755 本人 可读4可写2可执行1  其他人 可读4 可执行1 5
        {
            printf("已创建用户自己的本地共享目录：%s\n", shared_dir);
        } 
        else 
        {
            perror("创建共享目录失败");
        }
    }

    if (access(download_dir, F_OK) == -1) 
    {
        if (mkdir(download_dir, 0755) == 0) 
        {
            printf("已创建用户自己的共享下载目录：%s\n", download_dir);
        } 
        else 
        {
            perror("创建下载目录失败");
        }
    }
}


void shared_list_local(const char *username) //查看本地共享文件列表
{
    if (!username || strlen(username) == 0) 
    {
        printf("错误：用户名为空\n");
        return;
    }

    char shared_dir[256] = {0};
    get_shared_dir(username, shared_dir, sizeof(shared_dir));

    DIR *dir = opendir(shared_dir);
    if (!dir) 
    {
        perror("打开共享目录失败");
        return;
    }

    struct dirent *entry;//用于存储目录项(文件/子目录消息)
    printf("\n===== 本地共享文件列表（%s）=====\n", username);
    int count = 0;//计数，统计第几个文件了
    while ((entry = readdir(dir)) != NULL) 
    {
        if (entry->d_name[0] != '.')  // 排除隐藏文件和.、..
        { 
            printf("%d. %s\n", ++count, entry->d_name);
        }
    }
    if (count == 0) 
    {
        printf("提示：您的共享文件夹当中  暂无可共享文件，可将文件放入 %s 目录\n", shared_dir);
    }
    printf("====================================\n");
    closedir(dir);
}


void shared_start_service(const char *username) //仅初始化目录，无需网络监听，模拟共享目录
{
    if (!username || strlen(username) == 0) 
    {
        printf("错误：用户名为空，无法启动共享服务\n");
        return;
    }
    
    shared_init(username);// 仅初始化目录，默认共享已开启，模拟共享目录
    printf("共享文件夹服务已启动（用户：%s）\n", username);
}


void shared_get_friend_list(const char *friend_username) //获取好友的共享文件列表（直接读取本地好友共享目录）
{
    if (!friend_username || strlen(friend_username) == 0) 
    {
        printf("错误：好友用户名为空\n");
        return;
    }
    char friend_shared_dir[256] = {0};
    snprintf(friend_shared_dir, sizeof(friend_shared_dir), SHARED_DIR_TEMPLATE, friend_username);

    DIR *dir = opendir(friend_shared_dir);
    if (!dir) 
    {
        printf("错误：好友 %s 的共享目录不存在（可能未初始化）\n", friend_username);
        return;
    }

    // 显示好友共享文件列表
    struct dirent *entry;
    printf("\n===== %s 的共享文件列表 =====\n", friend_username);
    int count = 0;
    while ((entry = readdir(dir)) != NULL) 
    {
        if (entry->d_name[0] != '.') //排除隐藏文件
        {
            printf("%d. %s\n", ++count, entry->d_name);
        }
    }
    if (count == 0) 
    {
        printf("该好友暂无共享文件\n");
    }
    printf("===========================\n");
    closedir(dir);
}


void shared_download_file(const char *friend_username, const char *filename, const char *local_username) //下载好友的共享文件（直接本地复制）
{
    if (!friend_username || !filename || !local_username || strlen(friend_username) == 0 || strlen(filename) == 0 || strlen(local_username) == 0) 
        
        {
            printf("错误：参数不能为空,或者有误\n");
            return;
        }

   
    char friend_file[512] = {0}; //好友文件路径
    char local_save[512] = {0};//本地保存路径
    char friend_shared_dir[256] = {0};//好友的共享目录
    char local_download_dir[256] = {0};//本地下载路径

    snprintf(friend_shared_dir, sizeof(friend_shared_dir), SHARED_DIR_TEMPLATE, friend_username);
    snprintf(friend_file, sizeof(friend_file), "%s/%s", friend_shared_dir, filename);

    get_shared_download_dir(local_username, local_download_dir, sizeof(local_download_dir));
    snprintf(local_save, sizeof(local_save), "%s/%s", local_download_dir, filename);

    
    if (access(friend_file, F_OK) == -1) 
    {
        printf("错误：好友的文件 %s 不存在\n", filename);
        return;
    }

    // 打开文件进行复制
    int fd_from = open(friend_file, O_RDONLY);
    if (fd_from < 0) 
    {
        perror("打开好友文件失败");
        return;
    }

    int fd_to = open(local_save, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd_to < 0) {
        perror("创建本地文件失败");
        close(fd_from);
        return;
    }

    // 获取文件大小（用于进度显示）
    struct stat st;
    fstat(fd_from, &st);
    long long file_size = st.st_size;
    long long total_copied = 0;
    char buf[1024];
    ssize_t n;

    printf("开始复制 %s ...\n", filename);
    while ((n = read(fd_from, buf, sizeof(buf))) > 0) 
    {
        write(fd_to, buf, n);
        total_copied += n;
        // 显示进度百分比
        printf("\r已复制：%.2f%%", (double)total_copied / file_size * 100);
        fflush(stdout);//实时显示
    }
    printf("\n");

    close(fd_from);
    close(fd_to);

    if (total_copied == file_size) 
    {
        printf("文件复制成功，保存至：%s\n", local_save);
    } 
    else 
    {
        printf("复制失败，已复制 %lld/%lld 字节\n", total_copied, file_size);
        unlink(local_save);  // 删除不完整文件
    }
}